<template>
  <div>
    <div class="el-input-group">
      <el-select
        :style="{ width: inputWidth > 0 ? inputWidth + 'px' : '100%' }"
        v-model="data"
        filterable
        remote
        :remote-method="remoteMethod"
        :loading="loading"
        clearable
        @keyup.enter="search"
        @change="change"
        placeholder="请选择："
      >
        <el-option
          v-for="item in options"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <el-button class="el-input-group__append" @click="open" :icon="Search" />
    </div>
    <el-dialog
      v-model="dialogVisible"
      title="选择对话框"
      width="60%"
      append-to-body
      destroy-on-close
    >
      <div
        style="
          display: flex;
          margin-bottom: 10px;
          justify-content: space-between;
        "
      >
        <div style="display: flex">
          <el-checkbox @change="changeFuzzyQuery">模糊</el-checkbox>
          <el-button
            type="primary"
            @click="formSubmit"
            style="margin-left: 10px"
            >查 询</el-button
          >
        </div>
        <div>
          <el-button
            v-if="multipe"
            style="float: right"
            type="primary"
            plain
            @click="confirm"
            >确 定</el-button
          >
        </div>
      </div>
      <sc-form
        ref="formRef"
        :config="formConfig"
        v-model="formData"
        :modelValue="formData"
        style="margin-bottom: 5px"
      ></sc-form>
      <el-table
        ref="table"
        :data="tableData"
        :height="300"
        :lazy="lazy"
        :load="load"
        @row-click="click"
        row-key="id"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        @row-dblclick="dblclick"
        @select="selectRow"
        @select-all="selectAllRow"
      >
        <el-table-column v-if="multipe" type="selection" width="55" />
        <template v-for="(item, index) in tableConfig" :key="index">
              <el-table-column
              v-if="item.template&&item.template.nodes&&item.template.nodes[0].component == 'image'"
                :label="item.label"
                width="120"
              >
              <template #default="scope">
                <el-image style="height: 60px;" :src="scope.row[item.prop]"  preview-teleported></el-image>
              </template>
              </el-table-column>
              <el-table-column
                v-else-if="
                  item.template &&
                  item.template.nodes &&
                  item.template.nodes[0].component == 'switch'
                "
                :label="item.label"
                :width="flexWidth(item, tableData)"
              >
                <template #default="scope">
                  <el-switch
                    disabled
                    v-model="scope.row[item.prop]"
                    :active-value="item.template.nodes[0].activeValue"
                    :inactive-value="item.template.nodes[0].inactiveValue"
                  />
                </template>
              </el-table-column>
              <el-table-column
              v-else-if="item.prop"
                :prop="item.prop"
                :label="item.label"
                :width="flexWidth(item, tableData)"
              />
            </template>
        <slot></slot>
      </el-table>
      <div class="sc-table-select__page">
        <el-pagination
          small
          background
          layout="total,prev, pager, next"
          :total="total"
          :page-size="pageSize"
          v-model:currentPage="currentPage"
          @current-change="reload"
        ></el-pagination>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, watch,defineModel } from "vue";
import Api from "@/api/model/system";
import { deduplication, deepClone } from "@/utils/arr.js";
import { Search } from "@element-plus/icons-vue";
const emit = defineEmits(["update:modelValue", "updateRow", "selectRows"]);
const props = defineProps({
  modelValue: { type: String, default: "" },
  label: { type: String, default: "" },
  injectionKey: { type: String, default: "" },
  fileName: { type: Object, default: () => {} },
  template: { type: Object, default: ()=>{} },
  inputWidth: { type: Number, default: 0 },
  multipe: { type: Boolean, default: false },
  mapping: { type: Array, default: () => [] },
  initForm: { type: Object, default: () => {} }, //初始化条件
});
const loading = ref(false);
const remoteSearchQuery = ref();
const options = ref([]);
const reportData = ref([]);
const data = defineModel();
const tableData = ref([]);
const tableConfig = ref([]);
let mapTableConfig = [];
const flexColumnWidth = ref(true);
const total = ref(0);
const formConfig = ref({});
const formData = ref({});
const fuzzyQuery = ref(true);
const lazy = ref(false);
const currentPage = ref(1);
const pageSize = ref(20);
const dialogVisible = ref(false);
const multipeRow = ref([]);

const flag = watch(
  () => props.label,
  (newValue, oldValue) => {
    if(props.modelValue){
      options.value.push({
      value: props.modelValue,
      label: props.label,
    });
    }
    options.value = deduplication(options.value, "value");
  },
  {
    deep: true,
  }
);
watch(()=>props.initForm,()=>{
  Object.assign(formData.value, props.initForm);
},{deep:true})
onMounted(() => {
  if (props.label !== "") {
    options.value.push({
      value: props.modelValue,
      label: props.label,
    });
    options.value = deduplication(options.value, "value");
  }
  if (props.initForm) {
      Object.assign(formData.value, props.initForm);
    }
  mapTableConfig = props.mapping.map((ele) => {
    return ele.label;
  });
});
const flexWidth = (item, tableData, num = 0) => {
  if (
    item.flexColumnWidth == false ||
    tableData.length == 0 ||
    flexColumnWidth.value == false
  ) {
    // 表格没数据不做处理
    if (item.width) {
      return item.width;
    }
    return;
  }
  let flexWidth = 0; // 初始化表格列宽
  let columnContent = ""; // 占位最宽的内容
  let canvas = document.createElement("canvas");
  let context = canvas.getContext("2d");
  context.font = "14px Microsoft YaHei";
  if (item.prop === "" && item.title) {
    // 标题长内容少的，取标题的值,
    columnContent = item.title;
  } else {
    // 获取该列中占位最宽的内容
    let index = 0;
    for (let i = 0; i < tableData.length; i++) {
      const now_temp = tableData[i][item.prop] + "";
      const max_temp = tableData[index][item.prop] + "";
      const now_temp_w = context.measureText(now_temp).width;
      const max_temp_w = context.measureText(max_temp).width;
      if (now_temp_w > max_temp_w) {
        index = i;
      }
    }
    columnContent = tableData[index][item.prop];

    // 比较占位最宽的值跟标题、标题为空的留出四个位置
    const column_w = context.measureText(columnContent).width;
    const title_w = context.measureText(item.title).width;
    if (column_w < title_w) {
      columnContent = item.title || "占位符呀";
    }
  }
  // 计算最宽内容的列宽
  let width = context.measureText(columnContent);
  flexWidth = width.width + 40 + num;
  return flexWidth;
};
const search = async (e) => {
  options.value = []
  if (e.keyCode == 13 && remoteSearchQuery.value) {
    loading.value = true;
    if (props.mapping.length > 0) {
      props.mapping.forEach((ele) => {
        if (ele.label == props.template.label) {
          formData.value[ele.value] = remoteSearchQuery.value;
        }
      });
    } else {
      formData.value[props.template.label] = remoteSearchQuery.value;
    }
    let params = {
      fileName: props.fileName,
      fieldMap: formData.value,
      fuzzyQuery: true,
      injectionConditionKey: props.injectionKey,
    };
    console.log(params)
    let res = await Api.selectTable.post(params);
    loading.value = false;
    if (res.code == "200") {
      reportData.value = res.reportData.map((item) => {
        props.mapping.forEach((ele) => {
          if (ele.label !== ele.value) {
            item[ele.label] = item[ele.value];
            delete item[ele.value];
          }
        });
        return item;
      });
      reportData.value.forEach((item) => {
        let param = {
          label: item[props.template.label],
          value: item[props.template.value],
        };
        options.value.push(param);
      });
      options.value = deduplication(options.value, "value");
    }
  }
};
const change = (val) => {
  reportData.value.forEach((item) => {
    if (item[props.template.value] == val) {
      data.value = item[props.template.value];
      if (mapTableConfig.length > 0) {
            for (var key in item) {
              if (!mapTableConfig.includes(key)) {
                delete item[key];
              }
            }
          emit("updateRow", item);
        } else {
          emit("updateRow", item);
        }
        // emit("update:modelValue", data.value);
    }
  });
};
const remoteMethod = (query) => {
  if (query) {
    remoteSearchQuery.value = query;
  }
};
const open = () => {
  getInit();
  dialogVisible.value = true;
};
const changeFuzzyQuery = (val) => {
  fuzzyQuery.value = val;
};
const formSubmit = () => {
  getData();
};
const getData = async () => {
  tableData.value = [];
  var reqData = {
    fileName: props.fileName,
    pageSize: pageSize.value,
    pageNo: currentPage.value, //1
    fieldMap: formData.value,
    fuzzyQuery: fuzzyQuery.value,
    injectionConditionKey: props.injectionKey,
  };
  Object.assign(reqData);
  var res = await Api.select.query.post(reqData);
  if (res.code == "200") {
    flexColumnWidth.value = res.bean.table.flexColumnWidth;
    total.value = res.rows;
  }
  tableData.value = res.reportData.map((item) => {
    if (props.mapping.length > 0) {
      props.mapping.forEach((ele) => {
        if (ele.label !== ele.value) {
          item[ele.label] = item[ele.value];
          delete item[ele.value];
        }
      });
      return item;
    } else {
      return item;
    }
  });
};
const getInit = async () => {
  tableConfig.value = [];
  let params = {
    fileName: props.fileName,
    injectionConditionKey: props.injectionKey,
  };
  let res = await Api.report.selectCompanyList.post(params);
  if (res.code == 200) {
    formConfig.value = res.bean.form;
    lazy.value = res.bean.table.lazy;
  }
  res.bean.table.columns.forEach((item) => {
    if (props.mapping.length > 0) {
      props.mapping.forEach((ele) => {
        if (ele.value == item.prop) {
          item.prop = ele.label;
          // tableConfig.value.push(item)
        }
      });
      tableConfig.value.push(item);
    } else {
      tableConfig.value.push(item);
    }
  });
  getData();
};
const load = async (row, treeNode, resolve) => {
  let params = {
    parentId: row.id,
    fileName: props.fileName,
  };
  let res = await Api.select.query.post(params);
  let reportData = [];
  reportData = res.reportData.map((item) => {
    if (props.mapping.length > 0) {
      props.mapping.forEach((ele) => {
        if (ele.label !== ele.value) {
          item[ele.label] = item[ele.value];
          delete item[ele.value];
        }
      });
      return item;
    } else {
      return item;
    }
  });
  resolve(reportData);
};
const reload = () => {
  getData();
};
const click = (row) => {
  // if (props.multipe) {
  //   return;
  // }
  data.value = row[props.template.value];
  // emit("update:modelValue", data.value);
  let param = {
    value: row[props.template.value],
    label: row[props.template.label],
  };
  options.value.push(param);
  options.value = deduplication(options.value, "value");
  let data1 = deepClone(row);
  for (var key in data1) {
    if (mapTableConfig.length > 0) {
        if (!mapTableConfig.includes(key)) {
          delete data1[key];
        }
      }
  }
  emit("updateRow", data1);
};
const dblclick = () => {
  dialogVisible.value = false;
};
const selectRow = (rows, row) => {
  multipeRow.value = rows;
};
const selectAllRow = (rows) => {
  multipeRow.value = rows;
};
const confirm = () => {
  let data = multipeRow.value.map((ele) => {
    for (var key in ele) {
      if (mapTableConfig.length > 0) {
        if (!mapTableConfig.includes(key)) {
          delete ele[key];
        }
      }
    }
    return ele;
  });
  emit("selectRows", data);
  dialogVisible.value = false;
};
</script>
<style lang="scss" scoped>
.selectAppend {
  display: inline-flex;
  width: 100%;
  align-items: stretch;
}
:deep(.el-input__wrapper) {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
</style>
